﻿#include "MultiChannelMonitoringWindow.h"
#include <QMouseEvent>

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QResizeEvent>
#include <QDebug>
#include <QContextMenuEvent>
#include <QGridLayout>
#include <QDialog>
#include <QFormLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <sstream>
#include <QDir>
#include <map>
#include <vector>

#include "YCameraConfig.h"
#include "YCameraWidget.h"
#include "YCameraRecord.h"

#define CAM_CONF_PATH "cams.db"
//解决中文乱码
#define C(s) QString::fromLocal8Bit(s)

//渲染窗口
static YCameraWidget* cam_wids[16] = { 0 };

//视频录制
static std::vector<YCameraRecord*> records;

//存储视频日期时间
struct YCamVideo
{
	QString filepath;
	QDateTime datetime;
};
static std::map<QDate, std::vector<YCamVideo> > cam_videos;


MultiChannelMonitoringWindow::MultiChannelMonitoringWindow(QWidget* parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	//this->setWindowTitle("多路音视频监控项目");
	setAttribute(Qt::WA_DeleteOnClose, true);  // 关闭时自动销毁窗口

	//去除原窗口边框
	setWindowFlags(Qt::FramelessWindowHint);

	//布局head和body 垂直布局器
	auto vlay = new QVBoxLayout();
	//边框间距
	vlay->setContentsMargins(0, 0, 0, 0);
	//元素间距
	vlay->setSpacing(0);
	vlay->addWidget(ui.head);
	vlay->addWidget(ui.body);
	this->setLayout(vlay);

	//相机列表 和相机预览
	//水平布局器
	auto hlay = new QHBoxLayout();
	ui.body->setLayout(hlay);
	//边框间距
	hlay->setContentsMargins(0, 0, 0, 0);
	hlay->addWidget(ui.left);   //左侧相机列表
	hlay->addWidget(ui.cams);   //右侧预览窗口
	hlay->addWidget(ui.playback_wid);//回放窗口




	//////////////////////////////////////
	/// 初始化右键菜单
	// 视图=》  1 窗口
	//          4 窗口
	auto m = left_menu_.addMenu("视图");
	auto a = m->addAction("1窗口");
	connect(a, SIGNAL(triggered()), this, SLOT(View1()));
	a = m->addAction("4窗口");
	connect(a, SIGNAL(triggered()), this, SLOT(View4()));
	a = m->addAction("9窗口");
	connect(a, SIGNAL(triggered()), this, SLOT(View9()));
	a = m->addAction("16窗口");
	connect(a, SIGNAL(triggered()), this, SLOT(View16()));
	a = left_menu_.addAction("全部开始录制");
	connect(a, SIGNAL(triggered()), this, SLOT(StartRecord()));
	a = left_menu_.addAction("全部停止录制");
	connect(a, SIGNAL(triggered()), this, SLOT(StopRecord()));
	//默认九窗口
	View9();

	//刷新左侧摄像机列表
	YCameraConfig::Create()->Load(CAM_CONF_PATH);


	ui.time_list->clear();
	RefreshCams();

	//启动定时器渲染视频
	startTimer(1);
	Preview();//默认显示预览

}


void MultiChannelMonitoringWindow::SelectCamera(QModelIndex index)//选择摄像机
{
	qDebug() << "SelectCamera" << index.row();
	auto conf = YCameraConfig::Create();
	auto cam = conf->GetCamera(index.row()); //获取相机参数
	if (cam.name[0] == '\0')
	{
		return;
	}
	//相机视频存储路径
	std::stringstream ss;
	ss << cam.save_path << "/" << index.row() << "/";

	//遍历此目录
	QDir dir(ss.str().c_str());
	if (!dir.exists())
		return;
	//获取目录下文件列表
	QStringList filters;
	filters << "*.mp4" << "*.avi";
	dir.setNameFilters(filters);//筛选

	//清理其他相机的数据
	ui.cal->ClearDate();
	cam_videos.clear();

	//所有文件列表
	auto files = dir.entryInfoList();
	for (auto file : files)
	{
		//"cam_2020_09_04_17_54_58.mp4"
		QString filename = file.fileName();

		//去掉cam_ 和 .mp4
		auto tmp = filename.left(filename.size() - 4);
		tmp = tmp.right(tmp.length() - 4);
		//2020_09_04_17_54_58
		auto dt = QDateTime::fromString(tmp, "yyyy_MM_dd_hh_mm_ss");
		qDebug() << dt.date();
		ui.cal->AddDate(dt.date());
		//qDebug() << file.fileName();

		YCamVideo video;
		video.datetime = dt;
		video.filepath = file.absoluteFilePath();
		cam_videos[dt.date()].push_back(video);
	}

	//重新显示日期
	ui.cal->showNextMonth();
	ui.cal->showPreviousMonth();
}

void MultiChannelMonitoringWindow::SelectDate(QDate date)        //选择日期
{
	qDebug() << "SelectDate" << date.toString();
	auto dates = cam_videos[date];
	ui.time_list->clear();
	for (auto d : dates)
	{
		auto item = new QListWidgetItem(d.datetime.time().toString());

		//item 添加自定义数据 文件路径
		item->setData(Qt::UserRole, d.filepath);
		ui.time_list->addItem(item);
	}
}
void MultiChannelMonitoringWindow::PlayVideo(QModelIndex index)  //选择时间播放视频
{
	qDebug() << "PlayVideo" << index.row();
	auto item = ui.time_list->currentItem();
	if (!item)return;
	QString path = item->data(Qt::UserRole).toString();
	qDebug() << path;
	YPlayVideoPreviewWindow play;
	//play.Open(path.toLocal8Bit());
	play.Open("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/media/original400_300.mp4");
	play.exec();//模态窗口

}


void MultiChannelMonitoringWindow::View1()
{
	View(1);
}
void MultiChannelMonitoringWindow::View4()
{
	View(4);
}
void MultiChannelMonitoringWindow::View9()
{
	View(9);
}
void MultiChannelMonitoringWindow::View16()
{
	View(16);
}
void MultiChannelMonitoringWindow::View(int count)
{
	qDebug() << "View" << count;
	// 2X2 3X3 4X4
	//确定列数 根号
	int cols = sqrt(count);
	//总窗口数量
	int wid_size = sizeof(cam_wids) / sizeof(QWidget*);

	//初始化布局器
	auto lay = (QGridLayout*)ui.cams->layout();
	if (!lay)
	{
		lay = new QGridLayout();
		lay->setContentsMargins(0, 0, 0, 0);
		lay->setSpacing(2);//元素间距
		ui.cams->setLayout(lay);
	}
	//初始化窗口
	for (int i = 0; i < count; i++)
	{
		if (!cam_wids[i])
		{
			cam_wids[i] = new YCameraWidget();
			cam_wids[i]->setStyleSheet("background-color:rgb(51,51,51);");
		}
		lay->addWidget(cam_wids[i], i / cols, i % cols);
	}

	//清理多余的窗体
	for (int i = count; i < wid_size; i++)
	{
		if (cam_wids[i])
		{
			delete cam_wids[i];
			cam_wids[i] = nullptr;
		}
	}
}

//定时器渲染视频 回调函数
void MultiChannelMonitoringWindow::timerEvent(QTimerEvent* ev)
{
	//总窗口数量
	int wid_size = sizeof(cam_wids) / sizeof(QWidget*);
	for (int i = 0; i < wid_size; i++)
	{
		if (cam_wids[i])
		{
			//渲染多窗口视频
			cam_wids[i]->Draw();
		}
	}

}

void MultiChannelMonitoringWindow::StartRecord() //开始全部摄像头录制
{
	StopRecord();
	qDebug() << "开始全部摄像头录制";
	ui.status->setText("录制中。。。");
	//获取配置列表 
	auto conf = YCameraConfig::Create();
	int count = conf->GetCameraCount();
	for (int i = 0; i < count; i++)
	{
		auto cam = conf->GetCamera(i);
		std::stringstream ss;
		ss << cam.save_path << "/" << i << "/";
		QDir dir;
		dir.mkpath(ss.str().c_str());

		YCameraRecord* rec = new YCameraRecord();
		rec->set_rtsp_url(cam.url);
		rec->set_save_path(ss.str());
		rec->set_file_sec(5);
		rec->Start();
		records.push_back(rec);
	}

	//创建录制目录
	//分别开始录制线程
}
void MultiChannelMonitoringWindow::StopRecord()  //停止全部摄像头录制
{
	ui.status->setText("监控中。。。");
	for (auto rec : records)
	{
		rec->Stop();
		delete rec;
	}
	records.clear();
}

void MultiChannelMonitoringWindow::contextMenuEvent(QContextMenuEvent* event)
{
	//鼠标位置显示右键菜单
	left_menu_.exec(QCursor::pos());
	event->accept();
}

void MultiChannelMonitoringWindow::SetCam(int index)
{
	auto c = YCameraConfig::Create();
	QDialog dlg(this);
	if (index < 0)
	{
		dlg.setWindowTitle("添加相机");
	}
	else
	{
		dlg.setWindowTitle("编辑相机");
	}
	dlg.resize(400, 200);
	QFormLayout lay;
	dlg.setLayout(&lay);
	//  标题1 输入框1
	//  标题2 输入框2
	QLineEdit name_edit;
	name_edit.setFixedHeight(28);
	lay.addRow("名称", &name_edit);

	QLineEdit url_edit;
	url_edit.setFixedHeight(28);
	lay.addRow("主码流", &url_edit);

	QLineEdit sub_url_edit;
	sub_url_edit.setFixedHeight(28);
	lay.addRow("辅码流", &sub_url_edit);

	QLineEdit save_path_edit;
	save_path_edit.setFixedHeight(28);
	lay.addRow("保存目录", &save_path_edit);

	QPushButton save;
	save.setFixedSize(QSize(250, 40));
	save.setText("保存");

	connect(&save, SIGNAL(clicked()), &dlg, SLOT(accept()));

	lay.addRow("", &save);

	//编辑 读入原数据显示
	if (index >= 0)
	{
		auto cam = c->GetCamera(index);
		name_edit.setText(cam.name);
		url_edit.setText(cam.url);
		sub_url_edit.setText(cam.sub_url);
		save_path_edit.setText(cam.save_path);
	}


	for (;;)
	{
		if (dlg.exec() == QDialog::Accepted) //点击了保存
		{
			if (name_edit.text().isEmpty())
			{
				QMessageBox::information(0, "error", "请输入名称");
				continue;
			}
			if (url_edit.text().isEmpty())
			{
				QMessageBox::information(0, "error", "请输入主码流");
				continue;
			}
			if (sub_url_edit.text().isEmpty())
			{
				QMessageBox::information(0, "error", "请输入辅码流");
				continue;
			}
			if (save_path_edit.text().isEmpty())
			{
				QMessageBox::information(0, "error", "请输入保存目录");
				continue;
			}
			break;
		}
		return;
	}

	YCameraData data;
	strcpy(data.name, name_edit.text().toStdString().c_str());
	strcpy(data.url, url_edit.text().toStdString().c_str());
	strcpy(data.sub_url, sub_url_edit.text().toStdString().c_str());
	strcpy(data.save_path, save_path_edit.text().toStdString().c_str());
	if (index >= 0) //修改
	{
		c->ModifyCamera(index, data);
	}
	else //新增
	{
		c->Push(data);  //插入数据
	}
	c->Save(CAM_CONF_PATH); //保存到文件
	RefreshCams();  //刷新显示
}

void MultiChannelMonitoringWindow::SetCam()
{
	int row = ui.cam_list->currentIndex().row();
	if (row < 0)
	{
		QMessageBox::information(this, "error", "请选择摄像机");
		return;
	}
	SetCam(row);
}

void MultiChannelMonitoringWindow::DelCam()
{
	int row = ui.cam_list->currentIndex().row();
	if (row < 0)
	{
		QMessageBox::information(this, "error", "请选择摄像机");
		return;
	}
	std::stringstream ss;
	ss << "您确认需要删除摄像机"
		<< ui.cam_list->currentItem()->text().constData();
	ss << "吗？";

	if (
		QMessageBox::information(this,
			"confirm",
			ss.str().c_str(),
			QMessageBox::Yes,
			QMessageBox::No) != QMessageBox::Yes
		)
	{
		return;
	}
	YCameraConfig::Create()->DelCamera(row);
	RefreshCams();
}

void MultiChannelMonitoringWindow::AddCam()
{
	SetCam(-1);
}

void MultiChannelMonitoringWindow::RefreshCams()
{
	auto c = YCameraConfig::Create();
	ui.cam_list->clear();
	int count = c->GetCameraCount();
	for (int i = 0; i < count; i++)
	{
		auto cam = c->GetCamera(i);
		auto item = new QListWidgetItem(
			QIcon(":/XViewer/img/cam.png"), cam.name);
		ui.cam_list->addItem(item);
	}
}

void MultiChannelMonitoringWindow::Preview()//预览界面
{
	ui.cams->show();
	ui.playback_wid->hide();
	ui.preview->setChecked(true);
}

void MultiChannelMonitoringWindow::Playback()//回放界面
{
	ui.cams->hide();
	ui.playback_wid->show();
	ui.playback->setChecked(true);
}

void MultiChannelMonitoringWindow::MaxWindow()
{
	ui.max->setVisible(false);
	ui.normal->setVisible(true);
	showMaximized();
}

void MultiChannelMonitoringWindow::NormalWindow()
{
	ui.max->setVisible(true);
	ui.normal->setVisible(false);
	showNormal();
}

//窗口大小发生编码
void MultiChannelMonitoringWindow::resizeEvent(QResizeEvent* ev)
{
	int x = width() - ui.head_button->width();
	int y = ui.head_button->y();
	ui.head_button->move(x, y);
}
/////////////////////////////////////////////////////////////////////////////
/// 鼠标拖动窗口

static bool mouse_press = false;
static QPoint mouse_point;
void MultiChannelMonitoringWindow::mouseMoveEvent(QMouseEvent* ev)
{
	if (!mouse_press)
	{
		QWidget::mouseMoveEvent(ev);
		return;
	}
	this->move(ev->globalPos() - mouse_point);

}

void MultiChannelMonitoringWindow::mousePressEvent(QMouseEvent* ev)
{
	if (ev->button() == Qt::LeftButton)
	{
		mouse_press = true;
		mouse_point = ev->pos();
	}
}

void MultiChannelMonitoringWindow::mouseReleaseEvent(QMouseEvent* ev)
{
	mouse_press = false;
}

void MultiChannelMonitoringWindow::closeEvent(QCloseEvent* event) {
	event->accept();  // 接受关闭事件（允许关闭）
	Close();
	qDebug() << "窗口已关闭";
}

void MultiChannelMonitoringWindow::Close()
{
	//总窗口数量
	int wid_size = sizeof(cam_wids) / sizeof(QWidget*);
	for (int i = 0; i < wid_size; i++)
	{
		if (cam_wids[i])
		{
			//渲染多窗口视频
			cam_wids[i]->Stop();
		}
	}
}

MultiChannelMonitoringWindow::~MultiChannelMonitoringWindow()
{
}
